<template>
    <div>
       <!-- 面包屑导航区域 -->
        <el-breadcrumb separator-class="el-icon-arrow-right">
            <el-breadcrumb-item :to="{ path: '/home' }">首页</el-breadcrumb-item>
            <el-breadcrumb-item>权限管理</el-breadcrumb-item>
            <el-breadcrumb-item>角色列表</el-breadcrumb-item>
        </el-breadcrumb>

        <!-- 卡片视图区域 -->
        <el-card>
            <el-row>
                <el-col>
                    <!-- 添加角色按钮区域-->
                    <el-button type="primary" @click="addRolesVisible = true">添加角色</el-button>
                </el-col>
            </el-row>
            <!-- 角色列表区域 -->
            <el-table :data="roleList" stripe border>
                <el-table-column type="expand">
                    <template slot-scope="scope">
                        <el-row :class="['bdbottom',index1===0?'bdtop':'','vcenter']" v-for="(item1,index1) in scope.row.children" :key="item1.id">
                            <!-- 渲染一级权限 -->
                            <el-col :span="5">
                              <el-tag closable @close="removeRightById(scope.row,item1.id)" >{{item1.authName}}</el-tag>
                              <i class="el-icon-caret-right"></i>
                            </el-col>
                            <!-- 渲染二级和三级权限 -->
                            <el-col :span="19">
                                <el-row :class="[index2 == 0?'':'bdtop','vcenter']" v-for="(item2,index2) in item1.children" :key="item2.id">
                                    <!-- 通过 for 循环嵌套渲染二级权限 -->
                                    <el-col :span="6" >
                                        <el-tag @close="removeRightById(scope.row,item2.id)" closable type="success">{{item2.authName}}</el-tag>
                                        <i class="el-icon-caret-right"></i>
                                    </el-col>
                                    <!-- 通过 for 循环嵌套渲染三级权限 -->
                                    <el-col :span="18">
                                        <el-tag @close="removeRightById(scope.row,item3.id)" closable type="warning" v-for="(item3,index3) in item2.children" :key="item3.id">{{item3.authName}}</el-tag>
                                    </el-col>
                                </el-row>
                            </el-col>
                        </el-row>
                       <!-- <pre>
                           {{scope.row}}
                       </pre> -->
                    </template>
                </el-table-column>
                <!-- 索引列 -->
                <el-table-column label="序号" type="index"></el-table-column>
                <el-table-column label="角色名称" prop="roleName"></el-table-column>
                <el-table-column label="角色描述" prop="roleDesc"></el-table-column>
                <el-table-column label="操作" width="300px">
                    <!-- template slot-scope="scope"  作用域插槽 -->
                    <template slot-scope="scope">
                      <el-button size="mini" type="primary" icon="el-icon-edit" @click="editRolesBtn(scope.row.id)">编辑</el-button>
                      <el-button size="mini" type="danger" icon="el-icon-delete"  @click="removeRolesBtn(scope.row.id)">删除</el-button>
                      <el-button size="mini" type="warning" icon="el-icon-setting" @click="showSetRightDialog(scope.row)">分配权限</el-button>
                    </template>
                </el-table-column>
            </el-table>

        <!-- 添加角色 -->
        <el-dialog
        title="提示"
        :visible.sync="addRolesVisible"
        width="50%"
        @close="addRolesClosed"
        >
        <el-form :model="addForm" :rules="addFormrules" ref="addFormRef" label-width="70px">
            <el-form-item label-width="100px" label="角色名称" prop="roleName">
                <el-input v-model="addForm.roleName"></el-input>
            </el-form-item>
            <el-form-item label-width="100px" label="角色描述" prop="roleDesc">
                <el-input v-model="addForm.roleDesc"></el-input>
            </el-form-item>
        </el-form>
        <span slot="footer" class="dialog-footer">
            <el-button @click="addRolesVisible = false">取 消</el-button>
            <el-button type="primary" @click="addRoles">确 定</el-button>
        </span>
        </el-dialog>

        <!-- 修改角色信息 -->
        <el-dialog
        title="提示"
        :visible.sync="editRolesVisible"
        width="50%"
        @close="editRolesClosed"
        >
        <el-form :model="editForm" :rules="editFormrules" ref="editFormRef" label-width="70px">
            <el-form-item label-width="100px" label="角色名称" prop="roleName">
                <el-input v-model="editForm.roleName"></el-input>
            </el-form-item>
            <el-form-item label-width="100px" label="角色描述" prop="roleDesc">
                <el-input v-model="editForm.roleDesc"></el-input>
            </el-form-item>
        </el-form>
        <span slot="footer" class="dialog-footer">
            <el-button @click="editRolesVisible = false">取 消</el-button>
            <el-button type="primary" @click="addRoles">确 定</el-button>
        </span>
        </el-dialog>

        <!-- 分配权限对话框 -->
        <el-dialog
        title="分配权限"
        :visible.sync="setRightDialogVisible"
        width="50%"
        @close="setRightDialogClose"
        >
        <!-- 树形控件 -->
        <el-tree show-checkbox node-key="id" default-expand-all :default-checked-keys="defKeys" ref="treeRef" :data="rightlist" :props="treeProps"></el-tree>
        <span slot="footer" class="dialog-footer">
            <el-button @click="setRightDialogVisible = false">取 消</el-button>
            <el-button type="primary" @click="allotRights">确 定</el-button>
        </span>
        </el-dialog>
        
        </el-card>
    </div>
</template>

<script>
export default {
    data() {
        return {
           roleList:[],//角色列表数据 
           addRolesVisible:false,//添加角色弹框默认关闭
           //添加角色信息
           addForm:{
               roleName:'',
               roleDesc:'',
           },
           //添加表单的验证规则对象
            addFormrules:{
                roleName:[
                    { required: true, message: '请输入角色名称', trigger: 'blur' },
                    { min: 3, max: 10, message: '角色名称的长度在3~10个字符之间', trigger: 'blur' }
                ]
            },
            editRolesVisible:false,//修改角色弹框默认关闭
            editForm:{
               id:'',
               roleName:'',
               roleDesc:'',
           },
           //添加表单的验证规则对象
            editFormrules:{
                roleName:[
                    { required: true, message: '请输入角色名称', trigger: 'blur' },
                    { min: 3, max: 10, message: '角色名称的长度在3~10个字符之间', trigger: 'blur' }
                ]
            },
            setRightDialogVisible:false,//控制分配权限对话框的显示与隐藏
            //所有权限数据
            rightlist:[],
            //树形控件的属性绑定对象
            treeProps:{
                label:'authName',
                children:'children'
            },
            defKeys:[], // 默认选择的id值数组
            roleId:'',//当前即将分配权限的角色id
        }
    },
    created(){
        this.getRoleList();//获取角色列表数据
    },
    methods:{
        //获取角色列表数据
        async getRoleList(){
            const {data:res} =await this.$http.get(`roles`);
           if(res.meta.status !== 200){
               return;
               this.$message.error('获取角色列表失败');
           }else{
               this.roleList = res.data;
                //this.$message.success('获取角色列表成功');
           }
        },
        //添加角色
        addRoles(){
            this.$refs.addFormRef.validate(async valid =>{
                if(!valid){
                    return;
                }else{
                    const {data:res} = await this.$http.post(`roles`,{
                roleName:this.addForm.roleName,
                roleDesc:this.addForm.roleDesc,
            });
            if(res.meta.status !==201){
                return;
                this.$message.error('创建角色失败');
            }else{ 
                //关闭添加角色信息弹窗
                this.addRolesVisible = false;
                //获取角色列表数据
                this.getRoleList();
                this.$message.success(res.meta.msg);
            }
                }
            })
        },
         //关闭添加角色弹框
        addRolesClosed(){
             this.$refs.addFormRef.resetFields();
        },
        // 根据 ID 查询角色
        async editRolesBtn(id){
            this.editForm.id = id;
            const {data:res} = await this.$http.get(`roles/`+id);  
            this.editForm.roleName = res.data.roleName;
            this.editForm.roleDesc = res.data.roleDesc;
            this.editRolesVisible = true;
        },
        //修改角色信息
        addRoles(){
            this.$refs.editFormRef.validate(async valid =>{
                if(!valid){
                    return;
                }else{
            const {data:res} = await this.$http.put(`roles/`+ this.editForm.id,{
              roleName:this.editForm.roleName,
              roleDesc:this.editForm.roleDesc,
            });
            if(res.meta.status !== 200){
                return;
                this.$message.error('更新角色信息失败！');
            }else{
                //关闭修改角色信息弹窗
                this.editRolesVisible = false;
                //获取角色列表数据
                this.getRoleList();
                this.$message.success('更新角色信息成功！');
            }
                }
            })
        },
        //关闭修改角色弹框
        editRolesClosed(){
             this.$refs.editFormRef.resetFields();
        },
        //删除角色信息
        async removeRolesBtn(id){
            const res = await this.$confirm('此操作将永久删除该角色, 是否继续?', '提示', {
                confirmButtonText: '确定',
                cancelButtonText: '取消',
                type: 'warning'
                }).catch(err => err);
                console.log('res',res);
                //如果角色确认删除，则返回为字符串 confirm
                //如果角色取消删除，则返回为字符串 cancel
                if(res == 'confirm'){
                   const {data:ress} = await this.$http.delete(`roles/`+id);
                   if(ress.meta.status !== 200){
                        return;
                        this.$message.error(ress.meta.msg);
                   }else{
                        //提示更新成功
                        this.$message.success(ress.meta.msg);
                        //获取角色列表数据
                         this.getRoleList();
                   }
                }else{
                   return this.$message.info('取消删除成功'); 
                }
        },
        // 根据id删除对应的权限 
        async removeRightById(role,rightId){ 
            console.log(role,rightId);
            // 弹窗提示用户是否删除 
            const res = await this.$confirm('此操作将永久删除该权限, 是否继续?', '提示', {
                confirmButtonText: '确定',
                cancelButtonText: '取消',
                type: 'warning'
                }).catch(err => err);
                console.log('res',res);
                //如果角色确认删除，则返回为字符串 confirm
                //如果角色取消删除，则返回为字符串 cancel
                if(res == 'confirm'){
                   const {data:ress} = await this.$http.delete(`roles/${role.id}/rights/${rightId}`);
                   if(ress.meta.status !== 200){
                        return;
                        this.$message.error(ress.meta.msg);
                   }else{
                        //提示删除成功
                        this.$message.success(ress.meta.msg);
                        //获取角色列表数据
                        role.children = ress.data;
                   }
                }else{
                   return this.$message.info('取消删除成功'); 
                }
        },
        // 展示分配权限的对话框
        async showSetRightDialog(role){
            this.roleId = role.id;
            //获取所有权限数据
            const{data:res} = await this.$http.get(`rights/tree`);
            if(res.meta.status !== 200){
                return;
                this.$message.error(res.meta.msg);
            }else{
                //把获取到的权限数据保存到 data 中
                this.rightlist = res.data;
                this.$message.success(res.meta.msg);
            } 
            //递归获取三级节点的 Id
            this.getLeafKeys(role,this.defKeys);
            // 关闭权限分配的对话框
            this.setRightDialogVisible = true;
        },
        //通过递归的形式，获取角色下所有三级权限 id，并保存到数组 defKeys中
        getLeafKeys(node,arr){
            // 如果当前 node节点不包含 children属性。则是三级节点
            if(!node.children){
                return arr.push(node.id);
            }
            node.children.forEach(v =>
                this.getLeafKeys(v,arr)
            );
            
        },
        //监听关闭分配权限对话框 触发事件
        setRightDialogClose(){
            this.defKeys = [];
        },
        //点击为角色分配权限
        async allotRights(){
            const keys = [
                ...this.$refs.treeRef.getCheckedKeys(),
                ...this.$refs.treeRef.getHalfCheckedKeys(),
            ];
            const idStr = keys.join(',');
            const {data:res} = await this.$http.post(`roles/${this.roleId}/rights`,{
                rids:idStr
            });
            if(res.meta.status !== 200){
                return this.$message.error(res.meta.msg);
            }else{
                //获取角色列表数据
                this.getRoleList();
                this.setRightDialogVisible = false;
                this.$message.success(res.meta.msg);
            } 
            console.log(keys);
        }
    }
}
</script>
<style scoped>
    .el-tag{
        margin: 7px;
    }
    .bdtop{
        border-top:1px solid #eee;
    }
    .bdbottom{
        border-bottom:1px solid #eee;
    }
    .vcenter{
        display: flex;
        align-items: center;
    }
</style>